home *** CD-ROM | disk | FTP | other *** search
/ World of Sound / World of Sound.iso / utils / modplayers / tracker / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  7.9 KB  |  346 lines

  1. /* audio.c */
  2.  
  3. /* $Id: audio.c,v 3.9 1993/11/17 15:30:16 espie Exp espie $
  4.  * $Log: audio.c,v $
  5.  * Revision 3.9  1993/11/17  15:30:16  espie
  6.  * Added one level of abstraction. Look through player.c for the
  7.  * old high-level functions.
  8.  *
  9.  * Revision 3.8  1993/08/04  11:34:33  espie
  10.  * *** empty log message ***
  11.  *
  12.  * Revision 3.7  1993/07/18  10:39:44  espie
  13.  * Cleaned up some code.
  14.  *
  15.  * Revision 3.6  1992/11/27  10:29:00  espie
  16.  * General cleanup
  17.  *
  18.  * Revision 3.5  1992/11/24  10:51:19  espie
  19.  * Optimized output and fixed up some details.
  20.  * Unrolled code for oversample = 1 to be more efficient at
  21.  * higher frequency (since a high frequency is better than
  22.  * a higher oversample).
  23.  *
  24.  * Revision 3.4  1992/11/23  17:18:59  espie
  25.  * *** empty log message ***
  26.  *
  27.  * Revision 3.3  1992/11/23  10:12:23  espie
  28.  * Fixed up BIG bug.
  29.  *
  30.  * Revision 3.2  1992/11/20  14:53:32  espie
  31.  * Added finetune.
  32.  *
  33.  * Revision 3.1  1992/11/19  20:44:47  espie
  34.  * Protracker commands.
  35.  *
  36.  * Revision 3.0  1992/11/18  16:08:05  espie
  37.  * New release.
  38.  *
  39.  * Revision 2.14  1992/11/06  19:31:53  espie
  40.  * Fixed missing parameter type.
  41.  * fix_xxx for better speed.
  42.  * set_volume.
  43.  * Added possibility to get back to MONO for the sgi.
  44.  * Added stereo capabilities to the indigo version.
  45.  * Minor bug: a SAMPLE_FAULT is a minor error,
  46.  * we should first check that there was no other
  47.  * error before setting it.
  48.  * New resample function coming from the player.
  49.  * Added more notes.
  50.  *
  51.  * Revision 2.1  1991/11/17  23:07:58  espie
  52.  * Just computes some frequency-related parameters.
  53.  *
  54.  *
  55.  */
  56.  
  57. #include <math.h>
  58. #include <malloc.h>
  59. #include <stdio.h>
  60.  
  61. #include "defs.h"
  62. #include "extern.h"
  63. #include "song.h"
  64. #include "channel.h"
  65.      
  66. LOCAL char *id = "$Id: audio.c,v 3.9 1993/11/17 15:30:16 espie Exp espie $";
  67.  
  68.  
  69. /* DO_NOTHING is also used for the automaton */
  70. #define DO_NOTHING 0
  71. #define PLAY 1
  72. #define REPLAY 2
  73.  
  74. struct audio_channel
  75.     {
  76.     struct sample_info *samp;
  77.     int mode;
  78.     unsigned long pointer;
  79.     unsigned long step;
  80.     int volume;
  81.     int pitch;
  82.     } chan[4];
  83.  
  84. LOCAL struct sample_info dummy =
  85.     {
  86.     NULL,
  87.     0,
  88.     0,
  89.     0,
  90.     0,
  91.     0,
  92.     0,
  93.     0,
  94.     NULL,
  95.     NULL
  96.     };
  97.  
  98. LOCAL int allocated = 0;
  99.  
  100. struct audio_channel *new_channel()
  101.     {
  102.     struct audio_channel *new;
  103.     new = &chan[allocated++];
  104.     new->mode = DO_NOTHING;
  105.     new->pointer = 0;
  106.     new->step = 0;
  107.     new->pitch = 0;
  108.     new->volume = 0;
  109.     new->samp = &dummy;
  110.     return new;
  111.     }
  112.  
  113. void no_audio_channels()
  114.     {
  115.     allocated = 0;
  116.     }
  117.  
  118. /* Have to get some leeway for vibrato (since we don't bound pitch with
  119.  * vibrato). This is conservative.
  120.  */
  121. #define VIB_MAXDEPTH 150
  122.  
  123.  
  124. #define C fix_to_int(ch->pointer)
  125.  
  126. LOCAL unsigned long step_table[MAX_PITCH + VIB_MAXDEPTH];  
  127.                     /* holds the increment for finding the next sampled
  128.                      * byte at a given pitch (see resample() ).
  129.                      */
  130.  
  131. /* creates a table for converting ``amiga'' pitch
  132.  * to a step rate at a given resampling frequency.
  133.  * For accuracy, we don't use floating point, but
  134.  * instead fixed point ( << ACCURACY).
  135.  * IMPORTANT NOTE: we need to make it fit within 32 bits (long), which
  136.  * must be enough for ACCURACY + log2(max sample length)
  137.  */
  138. LOCAL void create_step_table(oversample, output_fr)
  139. int oversample;     /* we sample oversample i for each byte output */
  140. int output_fr;      /* output frequency */
  141.     {
  142.     double note_fr; /* note frequency (in Hz) */
  143.     double step;
  144.     int pitch;      /* amiga pitch */
  145.  
  146.     step_table[0] = 0;
  147.     for (pitch = 1; pitch < MAX_PITCH + VIB_MAXDEPTH; pitch++)
  148.         {
  149.         note_fr = AMIGA_CLOCKFREQ / pitch;
  150.             /* int_to_fix(1) is the normalizing factor */
  151.         step = note_fr / output_fr * int_to_fix(1) / oversample;
  152.         step_table[pitch] = (long)step;
  153.         }
  154.     }
  155.          
  156. LOCAL void readjust_pitch()
  157.     {
  158.     int i;
  159.     for (i = 0; i < allocated; i++)
  160.         chan[i].step = step_table[chan[i].pitch];
  161.     }
  162.  
  163. void init_tables(oversample, frequency, chan)
  164. int oversample, frequency;
  165. struct channel *chan;
  166.     {
  167.     create_step_table(oversample, frequency);
  168.     readjust_pitch();
  169.     }
  170.  
  171.  
  172. /* The playing mechanism itself.
  173.  * According to the current channel automata,
  174.  * we resample the instruments in real time to
  175.  * generate output.
  176.  */
  177. void resample(chan, oversample, number)
  178. struct channel *chan;
  179. int oversample;
  180. int number;
  181.     {
  182.     int i;          /* sample counter */
  183.     int channel;    /* channel counter */
  184.     int sampling;   /* oversample counter */
  185.     SAMPLE sample;  /* sample from the channel */
  186.     int value[NUMBER_TRACKS];
  187.                     /* recombinations of the various data */
  188.     struct audio_channel *ch;
  189.  
  190.         /* safety check: we can't have a segv there, provided
  191.          * chan points to a valid sample.
  192.          * For `empty' samples, what is needed is fix_length = 0
  193.          * and rp_start = NULL
  194.          */
  195.     /* special case optimization */
  196.     if (oversample == 1)
  197.         {
  198.             /* do the resampling, i.e., actually play sounds */
  199.         for (i = 0; i < number; i++) 
  200.             {
  201.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  202.                 {
  203.                 ch = chan[channel].audio;
  204.                 switch(ch->mode)
  205.                     {
  206.                 case DO_NOTHING:
  207.                     value[channel] = 0;
  208.                     break;
  209.                 case PLAY:
  210.                         /* Since we now have fix_length, we can
  211.                          * do that check with improved performance
  212.                          */
  213.                     if (ch->pointer < ch->samp->fix_length)
  214.                         {
  215.                         value[channel] = ch->samp->start[C] * ch->volume;
  216.                         ch->pointer += ch->step;
  217.                         break;
  218.                         }
  219.                     else
  220.                         {
  221.                         ch->mode = REPLAY;
  222.                         ch->pointer -= ch->samp->fix_length;
  223.                         }
  224.                 case REPLAY:
  225.                             /* is there a replay ? */
  226.                     if (!ch->samp->rp_start)
  227.                         {
  228.                         ch->mode = DO_NOTHING;
  229.                         break;
  230.                         }
  231.                     while (ch->pointer >= ch->samp->fix_rp_length)
  232.                         ch->pointer -= ch->samp->fix_rp_length;
  233.                     value[channel] = ch->samp->rp_start[C] * ch->volume;
  234.                     ch->pointer += ch->step;
  235.                     break;
  236.                     }
  237.                 } 
  238.             output_samples(value[0]+value[3], value[1]+value[2]);
  239.             }
  240.         }   
  241.     else
  242.         {
  243.         for (i = 0; i < number; i++) 
  244.             {
  245.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  246.                 {
  247.                 value[channel] = 0;
  248.                 for (sampling = 0; sampling < oversample; sampling++)
  249.                     {
  250.                     ch = chan[channel].audio;
  251.                     switch(ch->mode)
  252.                         {
  253.                     case DO_NOTHING:
  254.                         break;
  255.                     case PLAY:
  256.                             /* Since we now have fix_length, we can
  257.                              * do that check with improved performance
  258.                              */
  259.                         if (ch->pointer < ch->samp->fix_length)
  260.                             {
  261.                             value[channel] += ch->samp->start[C] * ch->volume;
  262.                             ch->pointer += ch->step;
  263.                             break;
  264.                             }
  265.                         else
  266.                             {
  267.                             ch->mode = REPLAY;
  268.                             ch->pointer -= ch->samp->fix_length;
  269.                             }
  270.                     case REPLAY:
  271.                                 /* is there a replay ? */
  272.                         if (!ch->samp->rp_start)
  273.                             {
  274.                             ch->mode = DO_NOTHING;
  275.                             break;
  276.                             }
  277.                         while (ch->pointer >= ch->samp->fix_rp_length)
  278.                             ch->pointer -= ch->samp->fix_rp_length;
  279.                         value[channel] += ch->samp->rp_start[C] * ch->volume;
  280.                         ch->pointer += ch->step;
  281.                         break;
  282.                         }
  283.                     } 
  284.                 }
  285.             output_samples((value[0]+value[3])/oversample, 
  286.                 (value[1]+value[2])/oversample);
  287.             }   
  288.         }
  289.  
  290.  
  291.     flush_buffer();
  292.     }
  293.  
  294.  
  295. /* setting up a given note */
  296.  
  297. void play_note(au, samp, pitch)
  298. struct audio_channel *au;
  299. struct sample_info *samp;
  300. int pitch;
  301.     {
  302.     au->pointer = 0;
  303.     au->pitch = pitch;
  304.     au->step = step_table[pitch];
  305.     if (samp)
  306.         {
  307.         au->samp = samp;
  308.         au->mode = PLAY;
  309.         }
  310.     else
  311.         au->mode = DO_NOTHING;
  312.     }
  313.  
  314. /* changing the current pitch (value
  315.  * may be temporary, and not stored
  316.  * in channel pitch, for instance vibratos.
  317.  */
  318. void set_play_pitch(au, pitch)
  319. struct audio_channel *au;
  320. int pitch;
  321.     {
  322.         /* save current pitch in case we want to change
  323.          * the step table on the run
  324.          */
  325.     au->pitch = pitch;
  326.     au->step = step_table[pitch];
  327.     }
  328.  
  329. /* changing the current volume. You HAVE to get through
  330.  * there so that it will work on EVERY machine.
  331.  */
  332. void set_play_volume(au, volume)
  333. struct audio_channel *au;
  334. int volume;
  335.     {
  336.     au->volume = volume;
  337.     }
  338.  
  339. void set_play_position(au, pos)
  340. struct audio_channel *au;
  341. int pos;
  342.     {
  343.     au->pointer = int_to_fix(pos);
  344.     }
  345.  
  346.